package mrpheu.demo.client.udp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;

import mrpheu.demo.basic.interfaces.IMrPheuOPC;


public class ChatUDPClient implements IMrPheuOPC {
    private DatagramSocket socket;
    private int serverPort;
    private String serverName;
    public static AtomicBoolean off = new AtomicBoolean(false);
    private BufferedReader streamIn = new BufferedReader(new InputStreamReader(System.in));
    
    private ExecutorService threadPool;
    
    private DatagramPacket packetServer;
    
    public ChatUDPClient(String serverName, int serverPort) {
        this.serverPort = serverPort;
        this.serverName = serverName;
        this.packetServer = null;
        this.threadPool = Executors.newSingleThreadExecutor();
    }
    
    @Override
    public boolean open() {
        System.out.println("Connecting to server....");
        DatagramSocket socketListen = null;
        try {
            this.socket = new DatagramSocket();
            socketListen = new DatagramSocket();
        } catch (SocketException e) {
            return false;
        }
        System.out.println("Create socket.");
        int listenPort = socketListen.getLocalPort();
        String openStr = String.valueOf(listenPort);
        byte[] buf = openStr.getBytes();
        InetAddress address = null;
        try {
            address = InetAddress.getByName(this.serverName);
        } catch (UnknownHostException e1) {
            return false;
        }
        DatagramPacket packetConnect = new DatagramPacket(buf, buf.length, address, this.serverPort);
        this.packetServer = (DatagramPacket)UDPIOImpl.connect(this.socket, packetConnect);
        System.out.println("fUCKED: " + this.socket.isClosed());
        if(this.packetServer.getData() == null) {
            System.out.println("Not receive from server");
        } else {
            byte[] dataByte = this.packetServer.getData();
            System.out.println("Server port: " + this.packetServer.getPort());
        }
        System.out.println("Connected");
        this.threadPool.execute(new ChatUDPClientThread(socketListen, this.packetServer));
        return true;
    }

    @Override
    public void process() {
        
        while(!ChatUDPClient.off.get()) {
            try {
                System.out.println("UDP Input: ");
                String line = this.streamIn.readLine();
                byte[] data = line.getBytes();
                if(this.packetServer != null) {
                    System.out.println("Port for send: " + this.socket.isClosed());
                    DatagramPacket packetData = new DatagramPacket(data, data.length, this.packetServer.getAddress(), this.packetServer.getPort());
                    if(!UDPIOImpl.sendData(this.socket, packetData)) {
                        System.out.println("Send fail!");
                    }
                    System.out.println("UDP: " + line);
                    ChatUDPClient.off.set(line.equals(".bye"));
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        this.close();
    }

    @Override
    public boolean close() {
        if(this.socket != null) {
            this.socket.close();
        }
        return true;
    }
    
    public void start() {
        this.open();
        this.process();
        //this.close();
    }

    public static void main(String[] args) {
        ChatUDPClient client = new ChatUDPClient("mrpheu-daviteq", 5432);
        client.start();
    }

}
